<template>
  <div class="other-config">
    <component
      :is="activeKey"
      ref="fieldObj"
      :other-config="otherConfig"
      :xtype="xtype"
      :config-info="configInfo"
      :func-data="funcInfo"
    ></component>
  </div>
</template>
<script>
  import { defineComponent, watch, ref } from 'vue';
  import { Hooks } from '@jecloud/ui';
  import { encode, decode, pick } from '@jecloud/utils';
  import { OTHER_CONFIG_CONSTANT, xtypeConfig } from './common/constant.js';
  import { useProvideOtherCOnfig } from './context';

  export default defineComponent({
    name: 'OtherConfig',
    components: {
      ...OTHER_CONFIG_CONSTANT,
    },
    props: {
      otherConfig: {
        type: String,
        default: '',
      },
      xtype: {
        type: String,
        default: '',
      },
      configInfo: {
        type: String,
        default: '',
      },
      funcInfo: {
        type: Object,
        default: () => {},
      },
    },
    emits: ['update:otherConfig'],
    setup(props, context) {
      //根据xtype激活对应的组件
      const moduleCode = xtypeConfig[props.xtype];
      const activeKey = ref(moduleCode);
      // v-model数据
      const otherConfig = Hooks.useModelValue({ props, context, key: 'otherConfig' });

      //子组件对象
      const fieldObj = ref();

      //监听xtype值变化切换组件
      watch(
        () => props.xtype,
        (newVal) => {
          if (newVal != undefined) {
            activeKey.value = xtypeConfig[newVal];
          }
        },
      );

      // 设置配置信息
      const setConfig = function (config) {
        Object.keys(config).map((key) => {
          config[key] = config[key] || '';
        });
        const object = decode(otherConfig.value) || {};
        Object.assign(object, config);
        otherConfig.value = encode(object);
      };

      // 暴露给子组件方法,可以通过inject获取
      useProvideOtherCOnfig({
        setConfig,
      });

      //监听otherConfig值变化给子组件重新赋值
      watch(
        () => props.otherConfig,
        (newVal) => {
          //新的otherConfig数据
          const config = decode(newVal ?? '{}') ?? {};
          //子组件的数据
          const childData = fieldObj.value.formState;
          //获取子组件对象的key
          const keys = Object.keys(childData);
          //提取otherConfig数据中子组件key的数据,返回新的数组
          const newObj = pick(config, keys);
          Object.assign(childData, newObj);
        },
      );

      //监听configInfo的数据
      watch(
        () => props.configInfo,
        (newVal) => {
          fieldObj.value.setOtherConfig(newVal, true);
        },
      );

      return { activeKey, fieldObj };
    },
  });
</script>
<style lang="less">
  .other-config {
    .prompt {
      margin: 0 0 0 10px;
      font-size: 14px;
      color: #3265f5;
      vertical-align: top;
      font-style: italic;
    }
  }
</style>
